﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Shohdi.DataHandler;
using DatabaseComponent;
using System.IO;
using ICSharpCode.SharpZipLib.Zip;

public partial class CoursesEN : System.Web.UI.Page
{
    bool titleIsOk = true;


    double mDegree = 75;


    long CoursesID
    {
        get
        {
            if (ViewState["CoursesID"] == null)
            {
                ViewState["CoursesID"] = System.Guid.NewGuid().ToString();
            }


            if (Session[ViewState["CoursesID"].ToString()] == null)
            {
                long obj = -1;
                Session[ViewState["CoursesID"].ToString()] = obj;

            }

            return (long)Session[ViewState["CoursesID"].ToString()];

        }
        set
        {
            if (ViewState["CoursesID"] == null)
            {
                ViewState["CoursesID"] = System.Guid.NewGuid().ToString();
            }

            Session[ViewState["CoursesID"].ToString()] = value;
        }
    }


    Courses objCourses
    {
        get
        {
            if (ViewState["objCourses"] == null)
            {
                ViewState["objCourses"] = System.Guid.NewGuid().ToString();
            }


            if (Session[ViewState["objCourses"].ToString()] == null)
            {
                Session[ViewState["objCourses"].ToString()] = new Courses();

            }

            return (Courses)Session[ViewState["objCourses"].ToString()];

        }
        set
        {
            if (ViewState["objCourses"] == null)
            {
                ViewState["objCourses"] = System.Guid.NewGuid().ToString();
            }

            Session[ViewState["objCourses"].ToString()] = value;
        }
    }



    



    /// <summary>
    /// it will check the security and customize the page
    /// </summary>
    /// <param name="currentPerson">the person to set security to his previleges</param>
    protected void checkSecurityAndCustomizePage(Persons currentPerson)
    {
        //Security Check

        if (!currentPerson.lstAllRulesIDs.Contains((long)RulesEnum.Courses_page))
            Response.Redirect("LoginEN.aspx");



        if (!currentPerson.lstAllRulesIDs.Contains((long)RulesEnum.Editing_courses_page))
        {
            btnSave.Enabled = false;
            btnDelete.Enabled = false;
        }





    }





    /// <summary>
    /// this function will check RequestID to detect update or insert
    /// </summary>
    protected void checkID()
    {
        if (Request["ID"] != null)
        {
            try
            {
                CoursesID = long.Parse(Request["ID"]);
                CoursesDB objCoursesDB = new CoursesDB(ConnectionStrings.LMS);
                List<Courses> lstCourses = objCoursesDB.getCoursesByID(CoursesID);
                if (lstCourses.Count > 0)
                {
                    if (lstCourses[0].StatusID == 2)
                        throw new Exception();

                    objCourses = lstCourses[0];
                    
                }
                else
                {
                    throw new Exception();

                }


                


            }
            catch
            {
                Response.Redirect("CoursesViewEN.aspx");
            }
        }
        else
        {
            btnDelete.Visible = false;
           
        }
    }


    


    /// <summary>
    /// this will bind the course data to update or delete
    /// </summary>
    protected void BindAllControls()
    {
        if (CoursesID != -1)
        {

            
            fc1.set(objCourses.FolderID);



            txtCourseNameAR.Text = objCourses.CourseNameAR;

            txtCourseNameEN.Text = objCourses.CourseNameEN;

            lblDateOfCreationValue.Text = objCourses.DateOfCreation.Value.ToString("dd/MM/yyyy");

            txtTargetAR.Text = objCourses.TargetAR;
            txtTargetEN.Text = objCourses.TargetEN;

            txtOutlineAR.Text = objCourses.OutlineAR;
            txtOutlineEN.Text = objCourses.OutlineEN;


            txtObjectivesAR.Text = objCourses.ObjectivesAR;
            txtObjectivesEN.Text = objCourses.ObjectivesEN;

            ddlLanguage.SelectedValue = objCourses.LanguageID.ToString();


            txtDuration.Text = GlobalVars.setSecounds(objCourses.Duration);


            hlPath.Text = objCourses.Path;
            txtPath.Text = objCourses.Path;
            hlPath.NavigateUrl = "~/LmsWebSite/CoursesFiles/" + objCourses.Path;


            txtDegree.Text = objCourses.objCoursesDegree.Degree.ToString("f2");

            
        }
    }



    


    /// <summary>
    /// this function will read all controls values
    /// </summary>
    protected void ReadAllControls()
    {

        objCourses.FolderID = fc1.get();


        objCourses.CourseNameEN = txtCourseNameEN.Text;
        objCourses.CourseNameAR = txtCourseNameAR.Text;

        if (CoursesID == -1)
        {
            ClassDataHandler con = new ClassDataHandler(ConnectionStrings.LMS);
            objCourses.DateOfCreation = con.GetServerDate();
        }

        objCourses.TargetEN = txtTargetEN.Text;
        objCourses.TargetAR = txtTargetAR.Text;

        objCourses.OutlineEN = txtOutlineEN.Text;
        objCourses.OutlineAR = txtOutlineAR.Text;

        objCourses.ObjectivesAR = txtObjectivesAR.Text;
        objCourses.ObjectivesEN = txtObjectivesEN.Text;

        objCourses.LanguageID = long.Parse(ddlLanguage.SelectedValue);

        if (txtDuration.Text.Trim().Equals(String.Empty))
        {
            txtDuration.Text = "0";
        }

        objCourses.Duration = GlobalVars.getSecounds(txtDuration.Text);


        if (fuPath.HasFile)
        {
            FileInfo fi = new FileInfo(fuPath.FileName);
            string strFileName =  System.Guid.NewGuid().ToString() + fi.Extension;

            try
            {
                fuPath.SaveAs(Server.MapPath("~/LmsWebSite/CoursesFiles/" + strFileName));
                objCourses.Path = strFileName;
            }
            catch
            {
                objCourses.Path = hlPath.Text;
            }
        }
        else
        {
            objCourses.Path = hlPath.Text;
        }


        objCourses.StatusID = 1;

        try
        {
            mDegree = double.Parse(txtDegree.Text);
        }
        catch
        {
            mDegree = 75;
        }

        
    }


    /// <summary>
    /// this function for clearing controls
    /// </summary>
    protected void clearAllControls()
    {

        fc1.set(-1);


        



        txtCourseNameAR.Text = "";

        txtCourseNameEN.Text = "";

        lblDateOfCreationValue.Text = "";

        txtTargetAR.Text = "";
        txtTargetEN.Text = "";

        txtOutlineAR.Text = "";
        txtOutlineEN.Text = "";


        txtObjectivesAR.Text = "";
        txtObjectivesEN.Text = "";
        
            txtDuration.Text = "";
        


        hlPath.Text = "";
        hlPath.NavigateUrl = "";
        txtPath.Text = "";

        txtDegree.Text = "";
        ddlLanguage.SelectedValue = "0";

        objCourses = new Courses();
        
    }




    protected void Page_Load(object sender, EventArgs e)
    {

       


        Persons currentPerson = GlobalVars.getCurrentPerson();

        


        if (!Page.IsPostBack)
        {
            
            checkSecurityAndCustomizePage(currentPerson);

            checkID();

            bindDdlLanguage();

            BindAllControls();

            
            

        }


        if (objCourses.ID != -1)
        {
            rfvPath.ControlToValidate = "txtPath";
        }
        else
            rfvPath.ControlToValidate = "fuPath";
    }



    /// <summary>
    /// this function will bind the ddl languages
    /// </summary>
    private void bindDdlLanguage()
    {
        LanguagesDB objLanguagesDB = new LanguagesDB(ConnectionStrings.LMS);
        List<Languages> lstLangs = objLanguagesDB.Select("", "");
        lstLangs = (from obj in lstLangs orderby obj.LanguageNameEN select obj).ToList<Languages>();
        ddlLanguage.DataSource = lstLangs;
        ddlLanguage.DataTextField = "LanguageNameEN";
        ddlLanguage.DataValueField = "ID";
        ddlLanguage.DataBind();
    }



   







   




    /// <summary>
    /// this function will Save the course
    /// </summary>
    protected void Save()
    {
        

        if (checkForRepeats())
        {
            CoursesDB objCoursesDB = new CoursesDB(ConnectionStrings.LMS);
            CoursesDegreeDB objCoursesDegreeDB = new CoursesDegreeDB(ConnectionStrings.LMS);
            CoursesDegree objCoursesDegree = new CoursesDegree();
            objCoursesDegree.Degree = mDegree;
            
            if (objCourses.ID == -1)
            {
                objCoursesDB.Insert(objCourses);

                objCoursesDegree.CoursesID = objCourses.ID;

                objCoursesDegreeDB.Insert(objCoursesDegree);

                clearAllControls();
                lblResult.Text = "Data saved ok.";
            }
            else
            {
                objCoursesDB.Update(objCourses);

                objCoursesDegree = objCourses.objCoursesDegree;

                objCoursesDegree.Degree = mDegree;

                objCoursesDegreeDB.Update(objCoursesDegree);

                //hlPath.NavigateUrl = "~/LmsWebSite/CourseFiles/" + objCourses.Path;
                //hlPath.Text = objCourses.Path;
                BindAllControls();
                lblResult.Text = "Data saved ok.";
            }

            

        }
        

    }

    /// <summary>
    /// this function will check if the course exist with the same Name or not
    /// </summary>
    /// <returns>true if ok , false for error (course exist before)</returns>
    protected bool checkForRepeats()
    {
        CoursesDB objCoursesDB = new CoursesDB(ConnectionStrings.LMS);



        List<Courses> lstOldCourses = objCoursesDB.getCoursesByCourseNameAR(objCourses.CourseNameAR);

        List<Courses> lstExist = new List<Courses>(from objOrg in lstOldCourses where (objOrg.FolderID == objCourses.FolderID && objOrg.CourseNameAR == objCourses.CourseNameAR && objOrg.ID != objCourses.ID ) select objOrg);

        if (lstExist.Count > 0)
        {

            errorExist();
            return false;
        }


        lstOldCourses = objCoursesDB.getCoursesByCourseNameEN(objCourses.CourseNameEN);

        lstExist = new List<Courses>(from objOrg in lstOldCourses where (objOrg.FolderID == objCourses.FolderID && objOrg.CourseNameEN == objCourses.CourseNameEN && objOrg.ID != objCourses.ID ) select objOrg);

        if (lstExist.Count > 0)
        {

            errorExist();
            return false;
        }
           


       

        return true;

    }


    /// <summary>
    /// this function will show a message with the error for existense
    /// </summary>
    private void errorExist()
    {
       
        lblError.Text = "Error , a course with the same name and path is already found , choose a new Name or path";
        
    }







    protected void btnSave_Click(object sender, EventArgs e)
    {

        //security check
        Persons currentPerson = GlobalVars.getCurrentPerson();
        if (!currentPerson.lstAllRulesIDs.Contains((long)RulesEnum.Editing_courses_page))
            return;


        if (Page.IsValid)
        {
            


            ReadAllControls();


            if (objCourses.Path == "")
            {
                lblError.Text = "Error the course must have a scorm file, please choose a file (zip)";
                return;
            }

            if (!checkFileAndGetCourseType())
            {
                if (!titleIsOk)
                {
                    lblError.Text = "Course didn't contain a title , please enter all name fields.";
                    return;
                }
                else
                {

                    lblError.Text = "Error the course must have a scorm file, this is not a scorm file (ZIP with mainfest.xml in the root path)";
                    return;
                }
            }


            Save();


        }
    }


    /// <summary>
    /// this function will check the course file and get its type (1 swf) mean Captivate else mean scorm
    /// </summary>
    private bool checkFileAndGetCourseType()
    {


        return buildCourseDir(objCourses);

    }




    /// <summary>
    /// this function will build the directory and get the toc
    /// </summary>
    /// <param name="objCourses">the course to build its directory and get its toc</param>
    private bool buildCourseDir(Courses objCourses)
    {
        Courses mObjCourses = objCourses;

        

        string strXmlName = GlobalVars.getCoursePath(objCourses) + "imsmanifest.xml";

        try
        {
            Directory.Delete(GlobalVars.getCoursePath(objCourses), true);
        }
        catch
        {
        }

        if (!File.Exists(strXmlName))
        {
            try
            {
                if (!Directory.Exists(GlobalVars.getCoursePath(objCourses)))
                    Directory.CreateDirectory(GlobalVars.getCoursePath(objCourses));

                FastZip fz = new FastZip();
                fz.ExtractZip(Server.MapPath("./CoursesFiles/" + objCourses.Path), GlobalVars.getCoursePath(objCourses), "");
            }
            catch
            {

            }
        }


        if (!File.Exists(strXmlName))
        {
            return false;

        }


        List<string> lstMeta = new List<string>(Courses.getCourseMetaData(objCourses));


        if (objCourses.CourseNameAR.Trim() == "" || objCourses.CourseNameEN.Trim() == "")
        {
            if (lstMeta.Count == 0)
            {
                titleIsOk = false;
                return false;

            }
            else if (lstMeta[0].Trim() == "")
            {
                titleIsOk = false;
                return false;
            }
            else
            {
                objCourses.CourseNameAR = lstMeta[0];
                objCourses.CourseNameEN = lstMeta[0];
            }
        }


        if (objCourses.OutlineAR.Trim() == "" && objCourses.OutlineEN.Trim() == "")
        {
            if (lstMeta.Count > 1)
            {
                objCourses.OutlineAR = lstMeta[1];
                objCourses.OutlineEN = lstMeta[1];
            }
        }


        List<imsitem> lstNew = imsitem.getListOfFile(strXmlName);



        bool bIsOK = false;

        bool bIsCaptivate = false;

        string strCaptivateFileName = "";

        checkListTogetValues(ref bIsOK, ref bIsCaptivate, ref strCaptivateFileName,lstNew);


        if (!bIsOK)
            return false;

        objCourses.isCaptivate = bIsCaptivate;
        objCourses.CaptivateFile = strCaptivateFileName;



        return true;


    }

    /// <summary>
    /// this function will get the values if it's captivate or not and if it's ok or not
    /// </summary>
    /// <param name="bIsOK">true for ok</param>
    /// <param name="bIsCaptivate">true for one file and one swf</param>
    /// <param name="strCaptivateFileName">the file name</param>
    /// <param name="lstNew">this is the list of items to get values from</param>
    private void checkListTogetValues(ref bool bIsOK, ref bool bIsCaptivate, ref string strCaptivateFileName, List<imsitem> lstNew)
    {
        List<imsitem> lstChilds = new List<imsitem>();

        foreach (imsitem obj in lstNew)
        {
            getLastChildOfIms(obj, lstChilds);
        }



        if (lstChilds.Count == 0)
        {
            bIsOK = false;
            bIsCaptivate = false;
            return;

        }
        else if (lstChilds.Count == 1)
        {
            bIsOK = true;
            
            foreach (string strFileObj in lstChilds[0].objResource.lstFiles)
            {
                if (strFileObj.ToLower() == "SCORM_support/scorm_support.swf".ToLower())
                {
                    foreach (string newStr in lstChilds[0].objResource.lstFiles)
                    {
                        if (newStr.Length > 4)
                        {
                            if (newStr.Substring(newStr.Length - 4).ToLower() == ".swf" && newStr.ToLower() != "SCORM_support/scorm_support.swf".ToLower())
                            {
                                strCaptivateFileName = GlobalVars.getCourseVirtualPath(objCourses) + newStr;
                                bIsCaptivate = true;
                                bIsOK = true;
                                return;

                            }

                        }
                    }
                }
            }
    
        }


        bIsOK = true;
        bIsCaptivate = false;
        return;


    }


    /// <summary>
    /// this function will get the childs recursive until it found a child wihout childs it add it to lstchilds
    /// </summary>
    /// <param name="obj">the item to search in</param>
    /// <param name="lstChilds">a list of childs to return value in</param>
    private void getLastChildOfIms(imsitem obj, List<imsitem> lstChilds)
    {
        if (obj.childs == null || obj.childs.Count == 0)
        {
            List<imsitem> lstFound = new List<imsitem>(from objOld in lstChilds where objOld.id == obj.id select objOld);
            if (lstFound.Count == 0)
                lstChilds.Add(obj);
        }
        
        else
        {
            foreach (imsitem childObject in obj.childs)
            {
                getLastChildOfIms(childObject, lstChilds);
            }


        }
    }


   
   


    


   



    /// <summary>
    /// this function will get the first child url recursive
    /// </summary>
    /// <param name="imsitem">the item to get its child url</param>
    /// <returns>the url returned</returns>
    private string getFirstUrlChild(imsitem imsitem)
    {
        if (imsitem.href != "")
            return imsitem.href;

        foreach (imsitem child in imsitem.childs)
        {
            string url = getFirstUrlChild(child);
            if (url != "")
                return url;
        }

        return "";

    }





    protected void btnDelete_Click(object sender, EventArgs e)
    {

        //security check
        Persons currentPerson = GlobalVars.getCurrentPerson();
        if (!currentPerson.lstAllRulesIDs.Contains((long)RulesEnum.Editing_courses_page))
            return;


        ReadAllControls();

        CoursesDB objCoursesDB = new CoursesDB(ConnectionStrings.LMS);
        List<Courses> lstCourses = new List<Courses>();
        lstCourses.Add(objCourses);




        if (objCourses.ID == -1)
        {
            lblError.Text = "No Courses to delete";
            lblResult.Text = "";
            return;
        }






        bool bRet = objCoursesDB.deleteAll(lstCourses[0]);
        if (bRet)
        {
            lblResult.Text = "Deleted ok.";
            clearAllControls();
        }
        else
        {
            lblError.Text = "Error Deleting.";
           
        }



            
          
       





    }


    




    protected void cvDuration_ServerValidate(object sender, ServerValidateEventArgs args)
    {
        if (GlobalVars.getSecounds(txtDuration.Text) == -1)
            args.IsValid = false;
        else
            args.IsValid = true;
    }



    protected void cvFolder_ServerValidate(object source, ServerValidateEventArgs args)
    {
        if (fc1.get() == -1)
            args.IsValid = false;
        else
            args.IsValid = true;
    }
    protected void cvDegree_ServerValidate(object source, ServerValidateEventArgs args)
    {
        double degree = 0;
        try
        {
            degree = double.Parse(txtDegree.Text);
        }
        catch
        {
            args.IsValid = false;
            return;
        }

        if (degree < 0 || degree > 100)
        {
            args.IsValid = false;
            return;
        }

        args.IsValid = true;
        return;

    }
}
